// Written by Dale J Williams.
// Licensed under MPL 1.1 unless otherwise specified. 
// http://www.mozilla.org/MPL/MPL-1.1.html

package engineDJW.effects {
	
	import flash.display.Sprite;
	
	/**
	 * ...
	 * @author Dale J Williams
	 */
	public class ParticleEmitter extends Sprite {
		
		private var _type		:Class;
		private var _limit		:int;
		private var _frequency	:int;
		private var _looping	:Boolean;
		private var _frame		:int;
		private var _particles	:Vector.<Particle>;
		private var _playing	:Boolean;
		
		public function ParticleEmitter($type:Class, $limit:int=10, $frequency:int=5, $looping:Boolean=false) {
			if (new $type(this) is Particle == false) 
				throw new Error("Particle Emitter can only accept particles.");
			_type = $type;
			_limit = $limit;
			_frequency = $frequency;
			_looping = $looping;
			init();
		}
		
		private function init():void {
			_particles = new Vector.<Particle>();
		}
		
		public function start():void {
			_playing = true;
			_frame = _frequency;
		}
		
		public function stop($hard:Boolean = false):void {
			if ($hard) removeAll();
			_playing = false;
		}
		
		public function update():void {
			for each(var particle:Particle in _particles) {
				particle.update();
				particle._count();
			}
			if (_frequency-- <= 0) return;
			if (_particles.length < _limit)
				add(new _type(this) as Particle);
			else if (!_looping) stop();
		}
		
		private function add($particle:Particle):void {
			_particles.push($particle);
			addChild($particle);
		}
		
		internal function remove($particle:Particle):void {
			var i:int = _particles.length;
			while (i--) {
				if (_particles[i] == $particle)
					removeChild(_particles.splice(i, 1)[0]);
			}			
		}
		
		private function removeAll():void {
			var i:int = _particles.length;
			while (i--) {
				removeChild(_particles.pop());
			}
		}
		
		public function get limit():int { return _limit; }		
		public function set limit(value:int):void {
			_limit = value;
		}
		
		public function get frequency():int { return _frequency; }		
		public function set frequency(value:int):void {
			_frequency = value;
		}
		
		public function get looping():Boolean { return _looping; }		
		public function set looping(value:Boolean):void {
			_looping = value;
		}
		
		public function get playing():Boolean { return _playing; }
		
	}

}